package com.lzx.hbh_system.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.api.R;
import com.lzx.hbh_system.bo.SysUser;
import com.lzx.hbh_system.bo.filter.Userfilter;
import com.lzx.hbh_system.dto.UserDto;
import com.lzx.hbh_system.log.SysLog;
import com.lzx.hbh_system.service.UserService;
import com.lzx.hbh_system.shiro.JWTToken;
import com.lzx.hbh_system.util.JWTUtil;
import com.lzx.hbh_system.util.RedisUtils;
import com.lzx.hbh_system.util.requestEntity.RequestView;
import com.lzx.hbh_system.util.responseEntity.RespOutMsgHeader;
import com.lzx.hbh_system.util.responseEntity.ResponseView;
import com.lzx.hbh_system.util.staitcParma.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * eq：添加权限认证的就需要对应的角色或者权限，若不加入对应注解，则说明这些方法可以让游客访问到，且不拦截请求正常访问
 * eq：Shiro登陆认证异常使用跳转转发，指定Controller处理并相应JSON格式给前端进行页面跳转，其余通过全局异常注解捕捉进行处理。
 * 问题记录：
 * 若没有权限则抛出异常  AuthorizationException 这里需要进行对应异常处理，验证失败处理响应
 * 后期完善...记录：2022-1-20-21点27分
 * 异常处理已完善...记录：2022-1-23-15点32分
 *
 *
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController extends BaseApiController {
    @Autowired
    private UserService userService;
    @RequiresPermissions(value = {"user:create"},logical = Logical.OR)
    @GetMapping("/test")
    public Object test(){
        Map<String,Object> map = new HashMap<>();
        map.put("aaa","bbbassddd sss");
        map.put("data",userService.list());
        return map;
    }
    @RequiresRoles(value = {"admin"},logical = Logical.OR)
    @PostMapping("/test2")
    public Object test2(){
        Map<String,Object> map = new HashMap<>();
        map.put("aaa","bbba22 sssss");
        SysUser sysUser = new SysUser();
        sysUser.setUserCode("1");
        sysUser.setUserName("1");
        sysUser = userService.getOneUser(sysUser);
        map.put("data",sysUser);
        return map;
    }
    @GetMapping("/getAllUserList")
    public ResponseView getAllUserList(){
        return userService.getAllUserList();
    }
    @PostMapping("/checklogin")
    public ResponseView checklogin(@RequestBody RequestView requestView, HttpServletRequest request) {
        //转对象
        Userfilter userfilter = JSONObject.parseObject(JSON.toJSONString(requestView.getMain()), Userfilter.class);
        ResponseView responseView = userService.CheckLoingUserByNameAndPwd(userfilter,request);
        return responseView;
    }
    @PostMapping("/getInfo")
    @RequiresAuthentication
    public ResponseView getInfo(@RequestBody RequestView requestView){
        //转对象
        Userfilter userfilter = JSONObject.parseObject(JSON.toJSONString(requestView.getMain()), Userfilter.class);
        ResponseView responseView = userService.getOneUserByUsername(userfilter);
        return responseView;
    }

    @PostMapping("/registerUser")
    public ResponseView registerUser(@RequestBody RequestView requestView){
        //转对象
        Userfilter userfilter = JSONObject.parseObject(JSON.toJSONString(requestView.getMain()), Userfilter.class);
        ResponseView responseView = userService.registerUser(userfilter);
        return responseView;
    }
    @SysLog(desc = "用户模块-密码修改操作")
    @PostMapping("/modifyUser")
    @RequiresAuthentication
    public ResponseView modifyUser(@RequestBody RequestView requestView){
        //转对象
        Userfilter userfilter = JSONObject.parseObject(JSON.toJSONString(requestView.getMain()), Userfilter.class);
        ResponseView responseView = userService.modifyUser(userfilter);
        return responseView;
    }
    /**
     * idea：获取当前登陆用户，subject.getPrincipal()得到我们重写的JWTToken的principal中返回的token，在JWTFilter里判断，该token是否过期，若没有过期则直接放行，就不需要查询数据库在登陆一遍
     * 免登录问题预想问题：若过期前，用户更改了密码，但是token此刻还是有效期，还是可以登陆的，如何解决呢》？？？？
     * eq: 对于更换密码来说，解决方案:前端在更改密码后重置情况当前用户token，这样就需要再次登陆。
     * eq：通过subject.getPrincipal()不能在关闭shiro的session情况下实现，只有在使用了shiro相关注解下的类和方法下才能获取当前登陆subject对象，否则将得不到subject的principal，具体快捷键 ctrl+2到达注释点说明（UserLogoutFilter.class文件）
     * eq：这里直接后台直接返回退出成功，前端把保存的token字符串删除掉，只能尽量使用token有效期短的来保证过期后token不能访问。不能完美确保token有效期内的安全访问
     * @return
     */
    @SysLog(desc = "用户模块-用户登出")
    @PostMapping("/logout")
    public ResponseView logout(@RequestBody RequestView requestView){//获取要退出的当前用户token，进行退出操作
        Userfilter userfilter = JSONObject.parseObject(JSON.toJSONString(requestView.getMain()), Userfilter.class);
        return userService.loginout(userfilter);
    }
    @PostMapping("/getAllUserPageFilter")
    public ResponseView getAllUserPageFilter(@RequestBody RequestView requestView){
        Userfilter userfilter = JSONObject.parseObject(JSON.toJSONString(requestView.getMain()), Userfilter.class);
        return userService.queryAllUserInfoPageFilter(userfilter);
    }
}
